home *** CD-ROM | disk | FTP | other *** search
/ Internet Info 1994 March / Internet Info CD-ROM (Walnut Creek) (March 1994).iso / networking / news / readers / nn / nn6.4.patch10 < prev    next >
Encoding:
Text File  |  1990-09-18  |  56.5 KB  |  2,189 lines

  1.          This is an official patch to nn release 6.4
  2.          -------------------------------------------
  3.  
  4.                    PATCH #10
  5.  
  6.                 Priority: HIGH
  7.  
  8.  
  9. NOTICE:  As descibed below one or two parts of this patch may be
  10. rejected by the "patch" program - if this happens to you, read the
  11. following description to see if you need to care (usually you don't!)
  12.  
  13. This patch fixes problems with 64k segment limitations on 286 based
  14. systems, a realloc error which could cause the nnmaster to crash as
  15. new groups are created, a bug in handling of aliased groups, some
  16. problems with missing Distribution: headers fooling Cnews, and ONE BIG
  17. BLUNDER in the mini-inews supplied with nn's initial release:
  18.  
  19. ===================================================================
  20.  
  21. When the mini-inews supplied with nn 6.4 is used, but the DOMAIN in
  22. conf.h has not been changed as required (and that is easy to over-
  23. look), all postings will look like they came from "iti.org" - and
  24. Steve Simmons is getting pretty tired of all the bounced mail for
  25. users unknown to iti.  To fix this, inews/conf.h is patched to contain
  26. an invalid domain name.
  27.  
  28. IF YOU HAVE MADE THE REQUIRED CHANGE TO THE DEFINITION OF DOMAIN IN
  29. inews/conf.h THIS PATCH WILL *FAIL* ON THE PART RELATED TO THAT FILE.
  30.  
  31. You can safely ignore this rejected patch since you have already done
  32. what is required to "fix" the problem.
  33.  
  34. ======================================================================
  35.  
  36. A syntax error in s-fortune.h is also fixed by this patch; if you are
  37. using that file now, you probably already fixed the bug, so that part
  38. of the patch is likely to fail as well - or worse, it may silently
  39. reintroduce the bug be reverting your own patch (the "patch" program
  40. is pretty stupid in that respect).
  41.  
  42. ===================================================================
  43.  
  44. When posting (also follow-ups) nn will now *always* generate a
  45. Distribution: header line, and the default distribution is now
  46. explicitly "world" (which is the implicit meaning of no Distribution
  47. in Bnews, but not in Cnews).
  48.  
  49. The facilities to control this are two new variables post-distribution
  50. and follow-distribution, and a change to the use of default-distribution.
  51. This is *not* documented in this patch, but the default values of the
  52. new variables will make everything work as usual.
  53.  
  54. ===================================================================
  55.  
  56. As usual, all changes are described in the updated RELEASE_NOTES file
  57. (read that for more details about this patch).  Thanks to all who
  58. reported bugs and provided fixes.
  59.  
  60. To apply this patch, use nn's :patch command, or run this command from
  61. the shell in the root of the nn source tree:
  62.     patch -p0 < this-article
  63.  
  64. Then run "make all" and "./inst u".
  65.  
  66. ++Kim Storm
  67.  
  68. *** ./LAST/active.c    Tue May 22 12:53:32 1990
  69. --- active.c    Tue Sep 11 17:53:18 1990
  70. ***************
  71. *** 90,103 ****
  72.           break;
  73.   
  74.        case '=':
  75. -         gh->master_flag |= M_ALIASED | M_IGNORE_A;
  76. -         if (old_flag & M_ALIASED) continue;
  77.           while (*++cp && isspace(*cp)) cp++;
  78.           name = cp;
  79.           while (*cp && !isspace(*cp)) cp++;
  80.           *cp = NUL;
  81. !         gh1 = lookup(name);
  82. !         gh->data_write_offset = (off_t)gh1->group_num;
  83.           must_update = 1;
  84.           break;
  85.       }
  86. --- 90,123 ----
  87.           break;
  88.   
  89.        case '=':
  90.           while (*++cp && isspace(*cp)) cp++;
  91.           name = cp;
  92.           while (*cp && !isspace(*cp)) cp++;
  93.           *cp = NUL;
  94. !         if (old_flag & M_ALIASED) {
  95. !         /* quick check: has the alias changed */
  96. !         int32 n = (int32)gh->data_write_offset;
  97. !         if (n >= 0 && n < master.number_of_groups) {
  98. !             gh1 = ACTIVE_GROUP(n);
  99. !             if (strcmp(gh1->group_name, name) == 0) {
  100. !             gh->master_flag |= M_ALIASED | M_IGNORE_A;
  101. !             continue;
  102. !             }
  103. !         }
  104. !         }
  105. !         gh1 = lookup_no_alias(name);
  106. !         if (gh1 == NULL) {
  107. !         /* '=unknown.group' is treated just like 'x' */
  108. !         if ((old_flag & M_IGNORE_A) == 0)
  109. !             log_entry('R', "Group %s aliased to unknown group (%s)",
  110. !                   gh->group_name, name);
  111. !         gh->master_flag |= M_IGNORE_A;
  112. !         if ((old_flag & (M_IGNORE_A|M_ALIASED)) == M_IGNORE_A)
  113. !             continue;
  114. !         } else {
  115. !         gh->master_flag |= M_ALIASED | M_IGNORE_A;
  116. !         gh->data_write_offset = (off_t)gh1->group_num;
  117. !         }
  118.           must_update = 1;
  119.           break;
  120.       }
  121. *** ./LAST/admin.c    Mon Jul 16 17:38:39 1990
  122. --- admin.c    Thu Sep  6 20:23:04 1990
  123. ***************
  124. *** 191,198 ****
  125.       articles = disk_use = 0;
  126.       nblocked = nignored = 0;
  127.   
  128. !     for (cur_group = 0; cur_group < master.number_of_groups; cur_group++) {
  129. !     gh = &active_groups[cur_group];
  130.   
  131.   #define DISK_BLOCKS(bytes) (((bytes) + 1023) / 1024)
  132.   
  133. --- 191,197 ----
  134.       articles = disk_use = 0;
  135.       nblocked = nignored = 0;
  136.   
  137. !     Loop_Groups_Header(gh) {
  138.   
  139.   #define DISK_BLOCKS(bytes) (((bytes) + 1023) / 1024)
  140.   
  141. ***************
  142. *** 564,570 ****
  143.           cur_group = (int)get_entry("Group number",
  144.                     0L, (long)(master.number_of_groups - 1));
  145.           if (cur_group >= 0)
  146. !         dump_m_entry(&active_groups[cur_group]);
  147.           break;
  148.   
  149.        case 'D':
  150. --- 563,569 ----
  151.           cur_group = (int)get_entry("Group number",
  152.                     0L, (long)(master.number_of_groups - 1));
  153.           if (cur_group >= 0)
  154. !         dump_m_entry(ACTIVE_GROUP(cur_group));
  155.           break;
  156.   
  157.        case 'D':
  158. ***************
  159. *** 572,584 ****
  160.           c = get_cmd(
  161.   "\nA)ll B)locked E)mpty H)oles I)gnored N)on-empty V)alid in(W)alid",
  162.   "DUMP");
  163. -         cur_group = -1;
  164.           pg_init(1, 1);
  165.   
  166. !         while (++cur_group < master.number_of_groups) {
  167.               if (s_keyboard || s_hangup) break;
  168. -             gh = &active_groups[cur_group];
  169.   #define NODUMP(cond) if (cond) continue; break
  170.               switch (c) {
  171.                case 'N':
  172. --- 571,580 ----
  173.           c = get_cmd(
  174.   "\nA)ll B)locked E)mpty H)oles I)gnored N)on-empty V)alid in(W)alid",
  175.   "DUMP");
  176.           pg_init(1, 1);
  177.   
  178. !         Loop_Groups_Header(gh) {
  179.               if (s_keyboard || s_hangup) break;
  180.   #define NODUMP(cond) if (cond) continue; break
  181.               switch (c) {
  182.                case 'N':
  183. ***************
  184. *** 595,600 ****
  185. --- 591,598 ----
  186.               NODUMP((gh->master_flag & M_VALID) == 0);
  187.                case 'W':
  188.               NODUMP(gh->master_flag & M_VALID);
  189. +              case 'A':
  190. +             break;
  191.                default:
  192.               s_keyboard = 1; continue;
  193.               }
  194. *** ./LAST/answer.c    Thu Jul 19 18:12:10 1990
  195. --- answer.c    Mon Sep 17 14:50:08 1990
  196. ***************
  197. *** 14,20 ****
  198.   extern char *temp_file;
  199.   extern char *news_lib_directory;
  200.   
  201. ! export char *default_distribution = NULL;
  202.   export char *extra_mail_headers    = NULL;
  203.   export char *extra_news_headers    = NULL;
  204.   export char *mail_record    = NULL;
  205. --- 14,26 ----
  206.   extern char *temp_file;
  207.   extern char *news_lib_directory;
  208.   
  209. ! #ifndef DEFAULT_DISTRIB
  210. ! #define DEFAULT_DISTRIB "world"
  211. ! #endif
  212. ! export char *default_distribution = DEFAULT_DISTRIB;
  213. ! export char *distribution_follow = "always same default";
  214. ! export char *distribution_post    = "ask default";
  215.   export char *extra_mail_headers    = NULL;
  216.   export char *extra_news_headers    = NULL;
  217.   export char *mail_record    = NULL;
  218. ***************
  219. *** 405,410 ****
  220. --- 411,448 ----
  221.       fclose(s);
  222.   }
  223.   
  224. + static char *get_distr(orig, distr)
  225. + char *orig, *distr;
  226. + {
  227. +     flag_type opts;
  228. +     int always, ask, same, dflt;
  229. +     char *str, *dd;
  230. +     if ((dd = default_distribution) == NULL) dd = DEFAULT_DISTRIB;
  231. +     if (distr == NULL) distr = "default";
  232. +     var_options(&distr, "always\0ask\0same\0default\0", &opts);
  233. +     always = (opts & FLAG(0));
  234. +     ask = (opts & FLAG(1));
  235. +     same = (opts & FLAG(2));
  236. +     dflt = (opts & FLAG(3));
  237. +     
  238. +     if (*distr == NUL || dflt) distr = dd;
  239. +     
  240. +     if (same && orig != NULL) {
  241. +     distr = orig;
  242. +     if (always) ask = 0;
  243. +     }
  244. +     
  245. +     if (!ask) return distr;
  246. +     
  247. +     prompt("Distribution: (default '%s') ", distr);
  248. +     str = get_s(NONE, NONE, NONE, NULL_FCT);
  249. +     if (str == NULL) return NULL;
  250. +     if (*str != NUL) distr = str;
  251. +     return distr;
  252. + }
  253.   answer(ah, command, incl)
  254.   article_header *ah;
  255.   int command;
  256. ***************
  257. *** 542,551 ****
  258.           ed_line++;
  259.       }
  260.   
  261. !     if (news.ng_dist) {
  262. !         fprintf(t, "Distribution: %s\n", news.ng_dist);
  263. !         ed_line++;
  264. !     }
  265.   
  266.       ref_line(t);
  267.   
  268. --- 580,589 ----
  269.           ed_line++;
  270.       }
  271.   
  272. !     str = get_distr(news.ng_dist, distribution_follow);
  273. !     if (str == NULL) goto close_t;
  274. !     fprintf(t, "Distribution: %s\n", str);
  275. !     ed_line++;
  276.   
  277.       ref_line(t);
  278.   
  279. ***************
  280. *** 911,933 ****
  281.       }
  282.       strcpy(summary, str);
  283.   
  284. !     if (post_distribution) {
  285. !     strcpy(distribution, post_distribution);
  286. !     } else {
  287. !     if (default_distribution != NULL)
  288. !         strcpy(distribution, default_distribution);
  289. !     else {
  290. !         strcpy(distribution, group_name);
  291. !         if (str = strchr(distribution, ',')) *str = NUL;
  292. !         if (str = strchr(distribution, '.')) *str = NUL;
  293. !     }
  294. !     prompt("Distribution: (default '%s') ", distribution);
  295. !     str = get_s(NONE, NONE, NONE, NULL_FCT);
  296.       if (str == NULL) goto no_post;
  297. -     if (*str) strcpy(distribution, str);
  298.       if (who_am_i == I_AM_POST) prompt_line++;
  299.       }
  300.   
  301.       new_temp_file();
  302.       if ((t = open_file(temp_file, OPEN_CREATE)) == NULL) {
  303. --- 949,960 ----
  304.       }
  305.       strcpy(summary, str);
  306.   
  307. !     if ((str = post_distribution) == NULL) {
  308. !     str = get_distr(NULL, distribution_post);
  309.       if (str == NULL) goto no_post;
  310.       if (who_am_i == I_AM_POST) prompt_line++;
  311.       }
  312. +     strcpy(distribution, str);
  313.   
  314.       new_temp_file();
  315.       if ((t = open_file(temp_file, OPEN_CREATE)) == NULL) {
  316. *** ./LAST/articles.c    Thu Jul 19 18:12:10 1990
  317. --- articles.c    Fri Aug 31 14:11:04 1990
  318. ***************
  319. *** 322,328 ****
  320.           cross_post = NETW_CROSS_INT(db_data.dh_cross[n]);
  321.           if (cross_post < 0 || cross_post >= master.number_of_groups)
  322.               continue;
  323. !         cpgh = &active_groups[cross_post];
  324.           if (cpgh == gh) {
  325.               if (seq_cross_filtering) continue;
  326.               n = db_hdr.dh_cross_postings;
  327. --- 322,328 ----
  328.           cross_post = NETW_CROSS_INT(db_data.dh_cross[n]);
  329.           if (cross_post < 0 || cross_post >= master.number_of_groups)
  330.               continue;
  331. !         cpgh = ACTIVE_GROUP(cross_post);
  332.           if (cpgh == gh) {
  333.               if (seq_cross_filtering) continue;
  334.               n = db_hdr.dh_cross_postings;
  335. *** ./LAST/conf/m-i80286.h    Sat Mar 31 23:12:48 1990
  336. --- conf/m-i80286.h    Fri Aug 31 14:13:08 1990
  337. ***************
  338. *** 13,18 ****
  339. --- 13,19 ----
  340.   typedef unsigned long    uint32;        /*       0 ..  2^31-1 */
  341.   
  342.   #define I286_BUG
  343. + #define MALLOC_64K_LIMITATION
  344.   
  345.   #ifdef NETWORK_DATABASE
  346.   
  347. *** ./LAST/conf/s-fortune.h    Mon Apr 23 18:32:50 1990
  348. --- conf/s-fortune.h    Tue Aug 28 11:33:24 1990
  349. ***************
  350. *** 1,4 ****
  351. - *******************************************************************
  352.   /*
  353.    *    This file is for Fortune 32:16 systems.
  354.    *    Use with m-m680x0.h file, but requires STRCSPN in config.h
  355. --- 1,3 ----
  356. *** ./LAST/conf/s-uport2-2.h    Mon Apr 23 18:32:44 1990
  357. --- conf/s-uport2-2.h    Thu Sep  6 19:47:42 1990
  358. ***************
  359. *** 12,17 ****
  360. --- 12,19 ----
  361.    *    Specify where the Bourne Shell is.
  362.    */
  363.   
  364. + #define AVOID_SHELL_EXEC
  365.   #undef    SHELL
  366.   #define    SHELL        "/bin/ksh"
  367.   
  368. *** ./LAST/db.c    Mon Jul 16 17:38:40 1990
  369. --- db.c    Tue Sep  4 13:18:29 1990
  370. ***************
  371. *** 13,19 ****
  372. --- 13,23 ----
  373.   import int db_data_subdirs;
  374.   
  375.   export master_header master;
  376. + #ifdef MALLOC_64K_LIMITATION
  377. + export group_header **active_groups = NULL;
  378. + #else
  379.   export group_header *active_groups = NULL;
  380. + #endif
  381.   export group_header **sorted_groups = NULL;
  382.   
  383.   export int  reread_groups_file = 0;  /* nnmaster -G */
  384. ***************
  385. *** 391,396 ****
  386. --- 395,404 ----
  387.       }
  388.   
  389.       freeobj(sorted_groups);
  390. + #ifdef MALLOC_64K_LIMITATION
  391. +     if (active_groups)
  392. +     Loop_Groups_Header(gh) freeobj(gh);
  393. + #endif
  394.       freeobj(active_groups);
  395.       active_groups = NULL;
  396.       sorted_groups = NULL;
  397. ***************
  398. *** 402,408 ****
  399. --- 410,422 ----
  400.       trust_master = (who_am_i != I_AM_MASTER || !reread_groups_file);
  401.   
  402.       db_sequential = 1;
  403. + #ifdef MALLOC_64K_LIMITATION
  404. +     Loop_Groups_Number(l_g_index) {
  405. +     gh = newobj(group_header, 1);
  406. +     active_groups[l_g_index] = gh;
  407. + #else
  408.       Loop_Groups_Header(gh) {
  409. + #endif
  410.       gh->group_num = l_g_index;
  411.       db_read_group(gh);
  412.       db_parse_group(gh, trust_master);
  413. ***************
  414. *** 418,425 ****
  415. --- 432,447 ----
  416.   {
  417.       master.free_groups = 20;
  418.   
  419. + #ifdef MALLOC_64K_LIMITATION
  420. +     active_groups = resizeobj(active_groups, group_header *,
  421. +                   master.number_of_groups + master.free_groups);
  422. + #else
  423.       active_groups = resizeobj(active_groups, group_header,
  424.                     master.number_of_groups + master.free_groups);
  425. +     clearobj(active_groups + master.number_of_groups, group_header,
  426. +          master.free_groups);
  427. + #endif
  428. +     
  429.       sorted_groups = resizeobj(sorted_groups, group_header *,
  430.                     master.number_of_groups + master.free_groups);
  431.   }
  432. ***************
  433. *** 502,514 ****
  434.   char *name;
  435.   {
  436.       register group_header *gh;
  437.   
  438.       gh = lookup_no_alias(name);
  439.       if (gh == NULL || (gh->master_flag & M_ALIASED) == 0) return gh;
  440.   
  441. !     do
  442. !     gh = &active_groups[gh->data_write_offset];
  443. !     while (gh->master_flag & M_ALIASED);
  444.   
  445.       return gh;
  446.   }
  447. --- 524,551 ----
  448.   char *name;
  449.   {
  450.       register group_header *gh;
  451. +     group_header *gh_na;
  452. +     register int32 n, x;
  453.   
  454.       gh = lookup_no_alias(name);
  455.       if (gh == NULL || (gh->master_flag & M_ALIASED) == 0) return gh;
  456.   
  457. !     gh_na = gh;
  458. !     x = 16;
  459. !     do {
  460. !     if (--x == 0) {
  461. !         log_entry('R', "Possible alias loop: %s", name);
  462. !         return gh_na;
  463. !     }
  464. !     n = (int32)gh->data_write_offset;
  465. !     /* if alias info is unreliable, return original group
  466. !        which will be ignored anyway */
  467. !     if (n < 0 || n >= master.number_of_groups) {
  468. !         log_entry('R', "Bad aliasing of %s -> %d", gh->group_name, n);
  469. !         return gh_na;
  470. !     }
  471. !     gh = ACTIVE_GROUP(n);
  472. !     } while (gh->master_flag & M_ALIASED);
  473.   
  474.       return gh;
  475.   }
  476. *** ./LAST/doc/RELEASE_NOTES    Thu Jul 19 18:12:11 1990
  477. --- doc/RELEASE_NOTES    Mon Sep 17 15:43:40 1990
  478. ***************
  479. *** 535,540 ****
  480. --- 535,542 ----
  481.   Prog:    nn
  482.   Title:    Unmark does not clear standout mode on HP terminals
  483.   From:    Bill Gaines <bill%iccdev@relay.EU.net>
  484. +     Hellmuth Michaelis <hm@hcshh.uucp> + fix
  485. + Fixed:    Patch #10 [term.c]
  486.   
  487.       On HP terminals, if you mark an article, and then unmark it, the
  488.       inverse video highlight does not go away.  You have to use "^L" to
  489. ***************
  490. *** 1049,1055 ****
  491. --- 1051,1169 ----
  492.   From:    chuq@Apple.COM (The Bounty Hunter)
  493.   Fixed:    Patch #9 [menu.c more.c]
  494.   
  495. + Prog:    nnusage
  496. + Title:    "nnusage -t" will print the header line last
  497. + From:    asd@mace.cc.purdue.edu (Kareth) + fix
  498. + Fixed:    Patch #10 [nnusage.sh]
  499.   
  500. + Prog:    nn
  501. + Title:    motd file is shown on every invocation of nn
  502. + From:    wilson@issun3.stc.nl (Tony Wilson)
  503. +     A.C.G.Saunders@newcastle.ac.uk (Aidan Saunders)
  504. + Fixed:    Patch #10 [nn.c]
  505. + Prog:    mini-inews
  506. + Title:    Default DOMAIN was iti.org causing problems if people didn't change it.
  507. + From:    scs@iti.org (Steve Simmons)
  508. + Fixed:    Patch #10 [inews/conf.h]
  509. + Prog:    nn
  510. + Title:    The support for the re-layout-read variable is not complete
  511. + From:    gemini%geminix@tub.uucp (Uwe Doering) + fix
  512. + Fixed:    Patch #10 [more.c]
  513. + Prog:    nnmaster
  514. + Title:    May crash when new groups are created - group header is not cleared.
  515. + From:    andrew@resam.dk (Leif Andrew Rump)
  516. +     Remi Saccoman <remi@framentec.fr> + fix
  517. + Fixed:    Patch #10 [db.c global.c global.h]
  518. + Prog:    mkprefix (and shell scripts)
  519. + Title:    /bin/sh is hardcoded in the #! line - SHELL should be used
  520. + From:    asd@mace.cc.purdue.edu (Kareth) + fix
  521. + Fixed:    Patch #10 [prefix.c]
  522. + Prog:    nn
  523. + From:    news@m2xenix.psg.com (Randy Bush)
  524. +     chl@cs.man.ac.uk (Charles Lindsey)
  525. + Title:    new-group-action 5 does not work (crash on new group).
  526. + Fixed:    Patch #10 [newsrc.c]
  527. + Prog:    nn
  528. + Title:    nnmaster crashes if active file contains alias to non-existing group.
  529. + From:    Mark Moraes <moraes@cs.toronto.edu> + fix
  530. +     jw@sics.se (Johan Widen)
  531. +     Liz Allen-Mitchell <liz@grian.cps.altadena.ca.us>
  532. + Fixed:    Patch #10 [active.c db.c]
  533. + Prog:    nn
  534. + Title:    "set boolean-var # comment" actually unsets boolean variable.
  535. + From:    jeffy@teda.uucp (Who? Me?)
  536. + Fixed:    Patch #10 [variable.c]
  537. + Prog:    nn
  538. + Title:    Gould's preprocessor defines "sel" which breaks newsrc code
  539. + From:    Eric Peterson <epeterson@encore.com>
  540. + Fixed:    Patch #10 [newsrc.c]
  541. + Prog:    all
  542. + Title:    Cannot handle more than 650 groups on 80286 machines
  543. + From:    John A. Limpert <johnl@n3dmc.svr.md.us>
  544. +     tkevans@fallst.UUCP (Tim Evans)
  545. + Fixed:    Patch #10 [admin.c articles.c db.c global.h kill.c master.c
  546. +     m-i80286.h sequence.c]
  547. + Prog:    nnusage
  548. + Title:    Option "-at" is not handled properly with ACCOUNTING on.
  549. +     (+ all unknown options were passed directly to nnacct).
  550. + From:    david@wraith.cs.uow.edu.au (David E A Wilson)
  551. + Fixed:    Patch #10 [nnusage.sh]
  552. + Prog:    nn
  553. + Title:    Duplicated articles on menu may have "-" entry before "subject" entry.
  554. + From:    gemini%geminix@tub.uucp (Uwe Doering)
  555. + Fixed:    Patch #10 [sort.c]
  556. + Prog:    nnmaster
  557. + Title:    Removed groups are not "ignored" if they were empty.
  558. + From:    Bernd Wechner <bernd@bhpcpd.kembla.oz.au>
  559. + Fixed:    Patch #10 [expire.c]
  560. + Prog:    nnadmin
  561. + Title:    M)aster D)ump A)ll did not work
  562. + From:    michi@ptcburp.ptcbu.oz.au (Michael Henning)
  563. + Fixed:    Patch #10 [admin.c]
  564. + Prog:    nn manual
  565. + Title:    delay-redraw variable was sometimes referenced as delayed-redraw
  566. + From:    shj@login.dkuug.dk (Stig Jacobsen)
  567. + Fixed:    Patch #10 [nn.1]
  568. + Prog:    nn
  569. + Title:    group regexp entries in kill cannot have multiple patterns
  570. + From:    asd@mace.cc.purdue.edu (Kareth)
  571. + Fixed:    Patch #10 [kill.c]
  572. + Prog:    scripts
  573. + Title:    uport must have AVOID_SHELL_EXEC defined.
  574. + From:    John A. Limpert <johnl@n3dmc.svr.md.us>
  575. + Fixed:    Patch #10 [s-uport2-2.h]
  576. + Prog:    nnmaster, nn
  577. + Title:    From: line packing sometimes produces an empty name
  578. + From:    Bernd Wechner <bernd@bhpcpd.kembla.oz.au> + fix
  579. + Fixed:    Patch #10 [pack_name.c]
  580. + Prog:    nn
  581. + Title:    G<return>a only works some of the time (and really bad in reading mode)
  582. + From:    David Lesher <wb8foz@mthvax.cs.miami.edu>
  583. + Fixed:    Patch #10 [group.c]
  584. +     In reading mode "Ga" silently expanded the level-1 menu rather
  585. +     than giving a new level-2 menu - or if it gave a level-2 menu
  586. +     it wasn't possible to repeat the command.
  587.   New features since initial 6.4.0 release
  588.   ----------------------------------------
  589.   
  590. ***************
  591. *** 1365,1367 ****
  592. --- 1479,1512 ----
  593.   Title:    Variables can now be set on nn command line with var=value.
  594.   From:    KFS on request from asd@mace.cc.purdue.edu (Kareth)
  595.   Added:    Patch #9 [sequence.c]
  596. + Prog:    inst
  597. + Title:    Patch level is now included in the installed manuals
  598. + From:    Tim Rylance <tkr@praxis.co.uk>
  599. + Added:    Patch #10 [inst.sh]
  600. + Prog:    nn
  601. + Title:    New variable: also-full-digest to include full digest when split=on
  602. + From:    KFS on request from Harry Herman <herman@corpane.uucp>
  603. + Added:    Patch #10 [nn.c variable.c nn.1]
  604. + Prog:    nn
  605. + Title:    "Searching..." is now shown while searching a pattern in an article
  606. + From:    bernd@bhpcpd.kembla.oz.au (Bernd Wechner)
  607. + Added:    Patch #10 [more.c]
  608. + Prog:    nn
  609. + Title:    kill-debug is turned off if ^G or 'q' is used during debug output
  610. + From:    KFS on request from iann@storesys.coles.oz.au (Ian Nicholls)
  611. + Added:    Patch #10 [kill.c term.c]
  612. + Prog:    nn
  613. + Title:    Made embedded-header-escape ('~') configureable
  614. + From:    KFS on request from bernd@bhpcpd.kembla.oz.au (Bernd Wechner)
  615. + Added:    Patch #10 [save.c variable.c nn.1]
  616. + Prog:    nn, nnpost
  617. + Title:    Added post-distribution and follow-distribution variables to improve
  618. +     generation of Distribution: headers.
  619. + From:    KFS
  620. + Added:    Patch #10 [answer.c variable.c]
  621. *** ./LAST/expire.c    Thu Jul 19 18:12:12 1990
  622. --- expire.c    Wed Sep  5 13:24:05 1990
  623. ***************
  624. *** 472,478 ****
  625.       if (gh->master_flag & M_IGNORE_GROUP) continue;
  626.   
  627.       if ((gh->master_flag & M_VALID) == 0) {
  628. -         if (gh->last_db_article == 0) continue;
  629.           log_entry('X', "Group %s removed", gh->group_name);
  630.           gh->master_flag |= M_IGNORE_A;
  631.           clean_group(gh);
  632. --- 472,477 ----
  633. *** ./LAST/global.c    Thu Jul 19 18:12:12 1990
  634. --- global.c    Thu Sep  6 17:09:42 1990
  635. ***************
  636. *** 740,745 ****
  637. --- 740,754 ----
  638.       return obj1;
  639.   }
  640.   
  641. + char *mem_clear(obj, size, nelt)
  642. + register char *obj;
  643. + unsigned size;
  644. + register int32 nelt;
  645. + {
  646. +     nelt *= size;
  647. +     while (--nelt >= 0) *obj++ = NUL;
  648. + }
  649.   mem_free(obj)
  650.   char *obj;
  651.   {
  652. *** ./LAST/global.h    Mon Jun 25 15:46:41 1990
  653. --- global.h    Fri Aug 31 18:33:14 1990
  654. ***************
  655. *** 177,182 ****
  656. --- 177,185 ----
  657.   #define    resizeobj(obj, type, nelt) \
  658.       (type *)mem_resize((char *)(obj), sizeof(type), (int32)(nelt))
  659.   
  660. + #define    clearobj(obj, type, nelt) \
  661. +     mem_clear((char *)(obj), sizeof(type), (int32)(nelt))
  662.   #define    freeobj(obj) mem_free((char *)(obj))
  663.   
  664.   #define quicksort(a,n,t,f) qsort((char *)(a), (unsigned)(n), sizeof(t), f)
  665. ***************
  666. *** 192,198 ****
  667. --- 195,205 ----
  668.   
  669.   /* group headers */
  670.   
  671. + #ifdef MALLOC_64K_LIMITATION
  672. + extern group_header **active_groups, **sorted_groups;
  673. + #else
  674.   extern group_header *active_groups, **sorted_groups;
  675. + #endif
  676.   
  677.   /* current group information */
  678.   
  679. ***************
  680. *** 209,218 ****
  681. --- 216,233 ----
  682.   #define    Loop_Groups_Number(num) \
  683.       for (num = 0; num < master.number_of_groups; num++)
  684.   
  685. + #ifdef MALLOC_64K_LIMITATION
  686. + #define Loop_Groups_Header(gh) \
  687. +     for (l_g_index = 0; \
  688. +      (l_g_index < master.number_of_groups) && \
  689. +      (gh = active_groups[l_g_index]) ;\
  690. +      l_g_index++)
  691. + #else
  692.   #define Loop_Groups_Header(gh) \
  693.       for (l_g_index = 0, gh=active_groups; \
  694.        l_g_index < master.number_of_groups; \
  695.        l_g_index++, gh++)
  696. + #endif
  697.   
  698.   #define Loop_Groups_Sorted(gh) \
  699.       for (l_g_index = s_g_first; \
  700. ***************
  701. *** 225,230 ****
  702. --- 240,251 ----
  703.   
  704.   #define    Loop_Groups_Newsrc(gh) \
  705.       for (gh = rc_sequence; gh; gh = gh->newsrc_seq)
  706. + #ifdef MALLOC_64K_LIMITATION
  707. + #define ACTIVE_GROUP(n)    active_groups[n]
  708. + #else
  709. + #define ACTIVE_GROUP(n)    &active_groups[n]
  710. + #endif
  711.   
  712.   /* 8 bit support (ISO 8859/...) */
  713.   
  714. *** ./LAST/group.c    Thu Jul 19 18:12:13 1990
  715. --- group.c    Thu Sep  6 23:46:43 1990
  716. ***************
  717. *** 114,119 ****
  718. --- 114,121 ----
  719.   }
  720.   
  721.   static int group_level = 0;
  722. + static article_number entry_first_article;
  723. + static int only_unread_articles;    /* menu contains only unread art. */
  724.   
  725.   static print_header()
  726.   {
  727. ***************
  728. *** 133,141 ****
  729.       if (no_update) {
  730.       so_printf(" NO UPDATE");
  731.       } else {
  732. !     if (current_group->current_first > current_group->first_article + 1)
  733.           so_printf((killed_articles > 0) ? "(L-%ld,K-%d)" : "(L-%ld)",
  734. !               current_group->current_first - current_group->first_article - 1,
  735.                 killed_articles);
  736.       else
  737.           if (killed_articles > 0)
  738. --- 135,144 ----
  739.       if (no_update) {
  740.       so_printf(" NO UPDATE");
  741.       } else {
  742. !     if ((current_group->group_flag & G_MERGED) == 0 &&
  743. !         current_group->current_first > entry_first_article)
  744.           so_printf((killed_articles > 0) ? "(L-%ld,K-%d)" : "(L-%ld)",
  745. !               current_group->current_first - entry_first_article,
  746.                 killed_articles);
  747.       else
  748.           if (killed_articles > 0)
  749. ***************
  750. *** 183,191 ****
  751. --- 186,198 ----
  752.       register group_header *mg_head;
  753.       flag_type entry_access_mode = access_mode;
  754.       extern flag_type parse_access_flags();
  755. +     article_number o_entry_first;
  756. +     int o_only_unread;
  757.   
  758.   #define    menu_return(cmd) { menu_cmd = (cmd); goto menu_exit; }
  759.   
  760. +     o_entry_first = entry_first_article;
  761. +     o_only_unread = only_unread_articles;
  762.       o_killed = killed_articles;
  763.       mark_var_stack();
  764.   
  765. ***************
  766. *** 257,262 ****
  767. --- 264,271 ----
  768.       }
  769.       
  770.       if (gh->current_first <= 0) gh->current_first = 1;
  771. +     entry_first_article = gh->current_first;
  772. +     only_unread_articles = (access_mode & ACC_ALSO_READ_ARTICLES) == 0;
  773.       
  774.       if (article_limit > 0) {
  775.           n = gh->last_db_article - article_limit + 1;
  776. ***************
  777. *** 351,356 ****
  778. --- 360,367 ----
  779.       } while (mg_head != NULL && (gh = gh->merge_with) != NULL);
  780.   
  781.       killed_articles = o_killed;
  782. +     entry_first_article = o_entry_first;
  783. +     only_unread_articles = o_only_unread;
  784.       restore_variables();
  785.       group_level--;
  786.   
  787. ***************
  788. *** 430,435 ****
  789. --- 441,448 ----
  790.       extern article_header *get_menu_article();
  791.       extern int get_from_macro;
  792.       extern group_header *jump_to_group;
  793. +     article_number o_cur_first = -1;
  794. +     group_header *read_mode_group;
  795.   
  796.   #define goto_return( cmd ) \
  797.       { menu_cmd = cmd; goto goto_exit; }
  798. ***************
  799. *** 438,443 ****
  800. --- 451,462 ----
  801.   
  802.       gh = orig_group = current_group;
  803.   
  804. +     if (ah != NULL) {    /* always open new level from reading mode */
  805. +     read_mode_group = orig_group;
  806. +     orig_group = NULL;
  807. +     } else
  808. +     read_mode_group = NULL;
  809. +     
  810.       mask = NULL;
  811.   
  812.       if (command == K_GOTO_GROUP)
  813. ***************
  814. *** 659,664 ****
  815. --- 678,687 ----
  816.       }
  817.   
  818.       if (gh != orig_group) {
  819. +     if (gh == read_mode_group) {
  820. +         o_cur_first = gh->current_first;
  821. +         gh->current_first = 0;
  822. +     }
  823.       if (gh->current_first > 0) {
  824.           msg("Group %s already active", gh->group_name);
  825.           goto_return(ME_NO_REDRAW);
  826. ***************
  827. *** 667,676 ****
  828.       }
  829.   
  830.       ans1 = ah ? 's' : 'a';
  831.       if (gh != orig_group) {
  832.       if (gh->unread_count > 0) ans1 = 'j';
  833.       } else {
  834. !     if (gh->unread_count > 0 && gh->current_first > (gh->first_article + 1))
  835.           ans1 = 'u';
  836.       else if (gh->current_first <= gh->first_db_article)
  837.           ans1 = 's';     /* no more articles to read */
  838. --- 690,702 ----
  839.       }
  840.   
  841.       ans1 = ah ? 's' : 'a';
  842. +     if (gh == read_mode_group) {
  843. +     ans1 = 's';
  844. +     } else
  845.       if (gh != orig_group) {
  846.       if (gh->unread_count > 0) ans1 = 'j';
  847.       } else {
  848. !     if (gh->unread_count > 0 && gh->current_first > entry_first_article)
  849.           ans1 = 'u';
  850.       else if (gh->current_first <= gh->first_db_article)
  851.           ans1 = 's';     /* no more articles to read */
  852. ***************
  853. *** 746,757 ****
  854.   
  855.       if (gh != orig_group) goto enter_new_level;
  856.   
  857. !     if (gh->current_first <= gh->first_db_article) {
  858.       msg("No extra articles");
  859.       goto_return(ME_NO_REDRAW);
  860.       }
  861.   
  862. !     if (access_group(gh, first, gh->current_first == gh->first_article + 1 ?
  863.                gh->last_db_article : gh->current_first - 1,
  864.                ACC_EXTRA_ARTICLES | ACC_ALSO_CROSS_POSTINGS |
  865.                ACC_ALSO_READ_ARTICLES | ACC_ONLY_READ_ARTICLES,
  866. --- 772,785 ----
  867.   
  868.       if (gh != orig_group) goto enter_new_level;
  869.   
  870. !     if (!only_unread_articles && gh->current_first <= gh->first_db_article) {
  871.       msg("No extra articles");
  872.       goto_return(ME_NO_REDRAW);
  873.       }
  874.   
  875. !     if (first < gh->first_db_article) first = gh->first_db_article;
  876. !     if (access_group(gh, first, only_unread_articles ?
  877.                gh->last_db_article : gh->current_first - 1,
  878.                ACC_EXTRA_ARTICLES | ACC_ALSO_CROSS_POSTINGS |
  879.                ACC_ALSO_READ_ARTICLES | ACC_ONLY_READ_ARTICLES,
  880. ***************
  881. *** 760,765 ****
  882. --- 788,794 ----
  883.       goto_return(ME_NO_REDRAW);
  884.       }
  885.   
  886. +     only_unread_articles = 0;
  887.       gh->current_first = first;
  888.       goto_return(ME_REDRAW);
  889.           
  890. ***************
  891. *** 819,830 ****
  892.    enter_new_level:
  893.       mark_memory(&mem_marker);
  894.       m_endinput();
  895.       menu_cmd = group_menu(gh, first, access_mode, mask, menu);
  896.       release_memory(&mem_marker);
  897.   
  898.    goto_exit:
  899.       if (gh != orig_group) {
  900. -     if (gh != NULL) gh->current_first = 0;
  901.       if (orig_group) init_group(orig_group);
  902.       }
  903.   
  904. --- 848,864 ----
  905.    enter_new_level:
  906.       mark_memory(&mem_marker);
  907.       m_endinput();
  908. +     if (o_cur_first < 0) o_cur_first = gh->current_first;
  909.       menu_cmd = group_menu(gh, first, access_mode, mask, menu);
  910.       release_memory(&mem_marker);
  911.   
  912.    goto_exit:
  913. +     if (gh && o_cur_first >= 0) gh->current_first = o_cur_first;
  914. +     if (read_mode_group)
  915. +     orig_group = read_mode_group;
  916.       if (gh != orig_group) {
  917.       if (orig_group) init_group(orig_group);
  918.       }
  919.   
  920. *** ./LAST/inews/conf.h    Mon Jun 25 15:46:42 1990
  921. --- inews/conf.h    Fri Jul 27 20:24:51 1990
  922. ***************
  923. *** 36,42 ****
  924.   #endif
  925.   
  926.   /*
  927. !  *  Define your local domain name.  You *must* define something here.
  928.    *
  929.    *  You are not strictly *required* to have a domain name; nonetheless
  930.    *  it's a good idea.  If you are on the Internet or otherwise have a
  931. --- 36,44 ----
  932.   #endif
  933.   
  934.   /*
  935. !  *  Define your local domain name.  You *must* define something, either
  936. !  *  here, in config.h, or elsewhere according to your local standards.
  937. !  *  See comment below on HIDDENNET.
  938.    *
  939.    *  You are not strictly *required* to have a domain name; nonetheless
  940.    *  it's a good idea.  If you are on the Internet or otherwise have a
  941. ***************
  942. *** 44,53 ****
  943.    *  a uucp-only site, use ".uucp" for now and go get a real name.
  944.    *
  945.    *  Note that if you imbed your domain name in the hostname and you don't
  946. !  *  use HIDDENNET, you should comment out the definition.
  947.    */
  948.   
  949. ! #define    DOMAIN    "iti.org"
  950.   
  951.   /*
  952.    *  If you define this, the hostname will not appear in the posting
  953. --- 46,57 ----
  954.    *  a uucp-only site, use ".uucp" for now and go get a real name.
  955.    *
  956.    *  Note that if you imbed your domain name in the hostname and you don't
  957. !  *  use HIDDENNET, you may get a period on the end of your fully qualified
  958. !  *  domian name (FQDN) in postings.  In that case, use HIDDENNET and
  959. !  *  define DOMAIN to be your FQDN.
  960.    */
  961.   
  962. ! /* #define    DOMAIN    "frobozz.com.bogus" */
  963.   
  964.   /*
  965.    *  If you define this, the hostname will not appear in the posting
  966. *** ./LAST/inst.sh    Mon Jul 16 17:38:44 1990
  967. --- inst.sh    Wed Aug 22 12:27:24 1990
  968. ***************
  969. *** 326,331 ****
  970. --- 326,332 ----
  971.       echo
  972.       echo Installing manuals
  973.   
  974. +     PL="`echo $VERSION | sed -e 's/ .*$//'`"
  975.       {
  976.           echo $UMAN_DIR $UMAN_SECT .1
  977.           echo $SMAN_DIR $SMAN_SECT .1m
  978. ***************
  979. *** 339,345 ****
  980.               do
  981.                   MAN=`basename ${i} $SRC`
  982.                   NEW=$DIR/${MAN}.$SECT
  983. !                 cp $i $NEW
  984.                   ./inst chmod 644 $NEW
  985.                   echo $MAN in $NEW
  986.               done
  987. --- 340,346 ----
  988.               do
  989.                   MAN=`basename ${i} $SRC`
  990.                   NEW=$DIR/${MAN}.$SECT
  991. !                 sed -e '/^\.TH /s/6.4/'${PL}'/' $i > $NEW
  992.                   ./inst chmod 644 $NEW
  993.                   echo $MAN in $NEW
  994.               done
  995. *** ./LAST/kill.c    Thu Jul 19 18:12:15 1990
  996. --- kill.c    Mon Sep 17 13:51:01 1990
  997. ***************
  998. *** 139,145 ****
  999.       if (do_select && (flag & AUTO_SELECT) == 0) goto failed;
  1000.       if (do_kill && (flag & AUTO_KILL) == 0) goto failed;
  1001.   
  1002. !     if (kill_debug) print_kill(kl);
  1003.   
  1004.       if (flag & KILL_UNLESS_MATCH)
  1005.           *unlessp = 1;
  1006. --- 139,145 ----
  1007.       if (do_select && (flag & AUTO_SELECT) == 0) goto failed;
  1008.       if (do_kill && (flag & AUTO_KILL) == 0) goto failed;
  1009.   
  1010. !     if (kill_debug && print_kill(kl) < 0) kill_debug = 0;
  1011.   
  1012.       if (flag & KILL_UNLESS_MATCH)
  1013.           *unlessp = 1;
  1014. ***************
  1015. *** 225,235 ****
  1016.       if (unless_match) goto did_kill;
  1017.   
  1018.    no_kill:
  1019. !     if (kill_debug) pg_end();
  1020.       return 0;
  1021.   
  1022.    did_kill:
  1023. !     if (kill_debug) pg_end();
  1024.       killed_articles++;
  1025.       return 1;
  1026.   }
  1027. --- 225,235 ----
  1028.       if (unless_match) goto did_kill;
  1029.   
  1030.    no_kill:
  1031. !     if (kill_debug && pg_end() < 0) kill_debug = 0;
  1032.       return 0;
  1033.   
  1034.    did_kill:
  1035. !     if (kill_debug && pg_end() < 0) kill_debug = 0;
  1036.       killed_articles++;
  1037.       return 1;
  1038.   }
  1039. ***************
  1040. *** 327,333 ****
  1041.       } else
  1042.       re = NULL;
  1043.   
  1044. !     killf = open_file(relative(nn_directory, "kill"), OPEN_APPEND);
  1045.       if (killf == NULL) {
  1046.       msg("cannot create kill file");
  1047.       return;
  1048. --- 327,333 ----
  1049.       } else
  1050.       re = NULL;
  1051.   
  1052. !     killf = open_file(relative(nn_directory, KILL_FILE), OPEN_APPEND);
  1053.       if (killf == NULL) {
  1054.       msg("cannot create kill file");
  1055.       return;
  1056. ***************
  1057. *** 608,617 ****
  1058.           if (fwrite(cp, sizeof(char), len, patternf) != len)
  1059.               goto err3;
  1060.           flag |= GROUP_REGEXP | GROUP_REGEXP_HDR ;
  1061. -         header.ckh_regexp_size++;
  1062.           } else {
  1063. !         if ((gh = lookup(cp)) == NULL) {
  1064. !             printf("Unknown group in kill file: %s\n", cp);
  1065.               any_errors++;
  1066.               goto drop_entry;
  1067.           }
  1068. --- 608,616 ----
  1069.           if (fwrite(cp, sizeof(char), len, patternf) != len)
  1070.               goto err3;
  1071.           flag |= GROUP_REGEXP | GROUP_REGEXP_HDR ;
  1072.           } else {
  1073. !         if ((gh = lookup(cp)) == NULL || (gh->master_flag & M_IGNORE_GROUP)) {
  1074. !             printf("Unknown/ignored group in kill file: %s\n", cp);
  1075.               any_errors++;
  1076.               goto drop_entry;
  1077.           }
  1078. ***************
  1079. *** 692,697 ****
  1080. --- 691,697 ----
  1081.           goto err3;
  1082.   
  1083.           header.ckh_entries++;
  1084. +         if (flag & GROUP_REGEXP) header.ckh_regexp_size++;
  1085.       }
  1086.       }
  1087.   
  1088. ***************
  1089. *** 838,844 ****
  1090.           tb++;
  1091.       } else
  1092.       if (entry.ck_group >= 0) {
  1093. !         gh = active_groups + entry.ck_group;
  1094.           kl->next_kill = (kill_list_entry *)(gh->kill_list);
  1095.           gh->kill_list = (char *)kl;
  1096.       } else {
  1097. --- 838,844 ----
  1098.           tb++;
  1099.       } else
  1100.       if (entry.ck_group >= 0) {
  1101. !         gh = ACTIVE_GROUP(entry.ck_group);
  1102.           kl->next_kill = (kill_list_entry *)(gh->kill_list);
  1103.           gh->kill_list = (char *)kl;
  1104.       } else {
  1105. *** ./LAST/man/nn.1.A    Tue Jun 12 11:46:44 1990
  1106. --- man/nn.1.A    Tue Sep 18 12:24:48 1990
  1107. ***************
  1108. *** 1106,1111 ****
  1109. --- 1106,1113 ----
  1110.   .I body
  1111.   of the article will be escaped by a tilde (e.g. ~From: ...) to enable
  1112.   \fInn\fP to split the folder into separate articles.
  1113. + The escape string can be redefined via the
  1114. + \fBembedded-header-escape\fP variable.
  1115.   .LP
  1116.   Articles can optionally be saved in MAIL or MMDF compatible format by
  1117.   setting the \fBmail-format\fP and \fBmmdf-format\fP variables.
  1118. *** ./LAST/man/nn.1.B    Mon Jul 16 17:38:46 1990
  1119. --- man/nn.1.B    Tue Sep 18 12:24:48 1990
  1120. ***************
  1121. *** 814,820 ****
  1122.   Has no effect besides redrawing the screen if necessary.  If an
  1123.   extended command (one which is prefixed by a :) produces any output
  1124.   requirering the screen to be redrawn, the screen will not be redrawn
  1125. ! immediately if the variable \fBdelayed-redraw\fP is set (useful on
  1126.   slow terminals).  Instead another \fB:\fP prompt is shown to allow you
  1127.   to enter a new extended command immediately.  It is sufficient to hit
  1128.   .B return
  1129. --- 814,820 ----
  1130.   Has no effect besides redrawing the screen if necessary.  If an
  1131.   extended command (one which is prefixed by a :) produces any output
  1132.   requirering the screen to be redrawn, the screen will not be redrawn
  1133. ! immediately if the variable \fBdelay-redraw\fP is set (useful on
  1134.   slow terminals).  Instead another \fB:\fP prompt is shown to allow you
  1135.   to enter a new extended command immediately.  It is sufficient to hit
  1136.   .B return
  1137. ***************
  1138. *** 898,903 ****
  1139.   \fIread\fP!
  1140.   .LP
  1141.   \fBRelated variables\fP:
  1142. ! backup, bug-report-address, delayed-redraw, keep-unsubscribed,
  1143.   unsubscribe-mark-read, mail, pager, sort-mode.
  1144.   .\" ENDPART B
  1145. --- 898,903 ----
  1146.   \fIread\fP!
  1147.   .LP
  1148.   \fBRelated variables\fP:
  1149. ! backup, bug-report-address, delay-redraw, keep-unsubscribed,
  1150.   unsubscribe-mark-read, mail, pager, sort-mode.
  1151.   .\" ENDPART B
  1152. *** ./LAST/man/nn.1.C    Thu Jul 19 18:12:17 1990
  1153. --- man/nn.1.C    Tue Sep 18 12:24:48 1990
  1154. ***************
  1155. *** 171,176 ****
  1156. --- 171,183 ----
  1157.   .LP
  1158.   The following variables are available:
  1159.   .TP
  1160. + \fBalso-full-digest\fP    (boolean, default false)
  1161. + When a digest is split, the digest itself is not normally included on
  1162. + the menu, and as such the initial adminstrative information is not
  1163. + available.  Setting \fBalso-full-digest\fP will cause the (unsplit)
  1164. + digest to be included on the menu.  These articles are marked with a @
  1165. + at the beginning of the subject.
  1166. + .TP
  1167.   \fBalso-subgroups\fP    (boolean, default true)
  1168.   When set, a group name in the presentation sequence will also cause
  1169.   all the subgroups of the group to be included, for example, comp.unix
  1170. ***************
  1171. *** 427,432 ****
  1172. --- 434,444 ----
  1173.   \fBeditor\fP \fIcommand\fP    (string, default not set)
  1174.   When set, it will override the current EDITOR environment variable
  1175.   when editing responses and new articles.
  1176. + .TP
  1177. + \fBembedded-header-escape\fP \fIstring\fP    (string, default '~')
  1178. + When saving an article to a file, header lines embedded in the body of
  1179. + the article are escaped using this string to make it possible for
  1180. + \fInn\fP to split the folder correctly afterwards.
  1181.   .TP
  1182.   \fBentry-report-limit\fP \fIarticles\fP    (integer, default 300)
  1183.   Normally, \fInn\fP will just move the cursor to the upper left corner
  1184. *** ./LAST/master.c    Thu Jul 19 18:12:18 1990
  1185. --- master.c    Fri Aug 31 14:11:01 1990
  1186. ***************
  1187. *** 272,278 ****
  1188. --- 272,283 ----
  1189.   
  1190.       master.free_groups--;
  1191.   
  1192. + #ifdef MALLOC_64K_LIMITATION
  1193. +     gh = newobj(group_header, 1);
  1194. +     active_groups[master.number_of_groups] = gh;
  1195. + #else
  1196.       gh = &active_groups[master.number_of_groups];
  1197. + #endif
  1198.   
  1199.       gh->group_name_length = strlen(name);
  1200.       gh->group_name = copy_str(name);
  1201. ***************
  1202. *** 803,809 ****
  1203.   
  1204.       arg = atol(bp);
  1205.       if (arg >= master.number_of_groups) continue;
  1206. !     gh = (arg >= 0) ? &active_groups[arg] : NULL;
  1207.       if ((bp = strchr(bp, ';')) == NULL) continue;
  1208.       bp++;
  1209.   
  1210. --- 808,814 ----
  1211.   
  1212.       arg = atol(bp);
  1213.       if (arg >= master.number_of_groups) continue;
  1214. !     gh = (arg >= 0) ? ACTIVE_GROUP(arg) : NULL;
  1215.       if ((bp = strchr(bp, ';')) == NULL) continue;
  1216.       bp++;
  1217.   
  1218. *** ./LAST/more.c    Thu Jul 19 18:12:19 1990
  1219. --- more.c    Thu Aug 23 19:02:39 1990
  1220. ***************
  1221. *** 36,41 ****
  1222. --- 36,42 ----
  1223.   import int  flush_typeahead;
  1224.   import int  case_fold_search;
  1225.   import int  echo_prefix_key;
  1226. + import int  re_layout;
  1227.   
  1228.   import char delayed_msg[];
  1229.   
  1230. ***************
  1231. *** 282,287 ****
  1232. --- 283,304 ----
  1233.       return buf;
  1234.   }
  1235.   
  1236. + static brief_header_line(ah, lno)
  1237. + register article_header *ah;
  1238. + int lno;
  1239. + {
  1240. +     int o_re_layout;
  1241. +     so_gotoxy(0, lno, 0);
  1242. +     so_printf("%s: ", ah->sender);
  1243. +     o_re_layout = re_layout;
  1244. +     if (re_layout_more >= 0) re_layout = re_layout_more;
  1245. +     prt_replies(ah->replies);
  1246. +     re_layout = o_re_layout;
  1247. +     so_printf("%s", ah->subject);
  1248. +     so_end();
  1249. + }
  1250.   more(ah, mode, screen_offset)
  1251.   article_header *ah;
  1252.   int mode, screen_offset;
  1253. ***************
  1254. *** 357,377 ****
  1255.       if (preview_window < 1 && Lines - screen_offset < min_pv_window)
  1256.           screen_offset = 0;
  1257.           else {
  1258. ! #ifdef notdef
  1259. !         so_printxy(0, screen_offset++, "%s: %s ", ah->sender, ah->subject);
  1260. ! #else
  1261. !         import int re_layout;
  1262. !         int o_re_layout;
  1263. !         so_gotoxy(0, screen_offset++, 0);
  1264. !         so_printf("%s: ", ah->sender);
  1265. !         o_re_layout = re_layout;
  1266. !         if (re_layout_more >= 0) re_layout = re_layout_more;
  1267. !         prt_replies(ah->replies);
  1268. !         re_layout = o_re_layout;
  1269. !         so_printf("%s", ah->subject);
  1270. !         so_end();
  1271. ! #endif
  1272.           if (!STANDOUT) screen_offset++;
  1273.           clrline();
  1274.       }
  1275. --- 374,380 ----
  1276.       if (preview_window < 1 && Lines - screen_offset < min_pv_window)
  1277.           screen_offset = 0;
  1278.           else {
  1279. !         brief_header_line(ah, screen_offset++);
  1280.           if (!STANDOUT) screen_offset++;
  1281.           clrline();
  1282.       }
  1283. ***************
  1284. *** 513,521 ****
  1285.               if (screen_offset == 0 && linenum == 1) {
  1286.               if (show_article_date) so_printxy(-1, 0, send_date);
  1287.   
  1288. !             /* so_printxy will cut subject */
  1289. !             so_printxy(0, lno, "%s: %s ", ah->sender, ah->subject);
  1290. !             lno++;
  1291.               if (!STANDOUT) lno++;
  1292.               }
  1293.           }
  1294. --- 516,522 ----
  1295.               if (screen_offset == 0 && linenum == 1) {
  1296.               if (show_article_date) so_printxy(-1, 0, send_date);
  1297.   
  1298. !             brief_header_line(ah, lno++);
  1299.               if (!STANDOUT) lno++;
  1300.               }
  1301.           }
  1302. ***************
  1303. *** 641,647 ****
  1304. --- 642,652 ----
  1305.           lno1 = lno;
  1306.       }
  1307.       } else
  1308. +     {
  1309. +     if (match_expr && linenum == match_botline)
  1310. +         msg("Searching...");
  1311.       linenum++;
  1312. +     }
  1313.   
  1314.       lp = linebuf;
  1315.       col = 0;
  1316. ***************
  1317. *** 1301,1306 ****
  1318. --- 1306,1312 ----
  1319.           if (regular_expr) freeobj(regular_expr);
  1320.           if (case_fold_search) fold_string(fname);
  1321.           regular_expr = regcomp(fname);
  1322. +         match_lines = 0;
  1323.       }
  1324.   
  1325.        case K_NEXT_MATCH:
  1326. *** ./LAST/newsrc.c    Thu Jul 19 18:12:20 1990
  1327. --- newsrc.c    Mon Sep  3 17:44:39 1990
  1328. ***************
  1329. *** 10,18 ****
  1330. --- 10,24 ----
  1331.   #include "term.h"
  1332.   #include "articles.h"
  1333.   
  1334. + #ifdef sel
  1335. + /* Remove Gould SELbus software name collision */
  1336. + #undef sel
  1337. + #endif
  1338.   #define TR(arg) printf arg
  1339.   
  1340.   import char *news_lib_directory, *db_directory;
  1341. + import char *home_directory;
  1342.   import char *pname;
  1343.   
  1344.   import int  verbose;
  1345. ***************
  1346. *** 177,183 ****
  1347.   #define MAX_RNLAST_LINE 6
  1348.   
  1349.   static char *rnlast_line[MAX_RNLAST_LINE];
  1350. ! static char *rnlast_path;
  1351.   
  1352.   static time_t get_last_new()
  1353.   {
  1354. --- 183,189 ----
  1355.   #define MAX_RNLAST_LINE 6
  1356.   
  1357.   static char *rnlast_line[MAX_RNLAST_LINE];
  1358. ! #define rnlast_path relative(home_directory, ".rnlast")
  1359.   
  1360.   static time_t get_last_new()
  1361.   {
  1362. ***************
  1363. *** 187,193 ****
  1364.       time_t t;
  1365.   
  1366.       if (new_group_action == RCX_RNLAST) {
  1367. -     rnlast_path = home_relative(".rnlast");
  1368.       lf = open_file(rnlast_path, OPEN_READ);
  1369.       if (lf == NULL) goto no_file;
  1370.   
  1371. --- 193,198 ----
  1372. ***************
  1373. *** 243,249 ****
  1374.       else /* can't be perfect -- don't update */
  1375.           fputs(rnlast_line[RN_ACTIVE_TIMES_OFFSET], lf);
  1376.       for (i = 0; i < MAX_RNLAST_LINE; i++) freeobj(rnlast_line[i]);
  1377. -     freeobj(rnlast_path);
  1378.       } else {
  1379.       lf = open_file(relative(nn_directory, "LAST"), OPEN_CREATE|MUST_EXIST);
  1380.       fprintf(lf, "%ld\n%s\n", (long)lastg->creation_time, lastg->group_name);
  1381. --- 248,253 ----
  1382. *** ./LAST/nn.c    Thu Jul 19 18:12:21 1990
  1383. --- nn.c    Wed Aug 22 13:45:32 1990
  1384. ***************
  1385. *** 32,37 ****
  1386. --- 32,38 ----
  1387.   export int
  1388.       article_limit = -1,
  1389.       also_read_articles = 0,
  1390. +     also_full_digest = 0,
  1391.       batch_mode = 0,
  1392.       conf_auto_quit = 0,
  1393.       do_kill_handling = 1,
  1394. ***************
  1395. *** 141,146 ****
  1396. --- 142,149 ----
  1397.       access_mode |= ACC_ALSO_READ_ARTICLES;
  1398.       if (dont_split_digests)
  1399.       access_mode |= ACC_DONT_SPLIT_DIGESTS;
  1400. +     if (also_full_digest)
  1401. +     access_mode |= ACC_ALSO_FULL_DIGEST;
  1402.       if (dont_sort_articles)
  1403.       access_mode |= ACC_DONT_SORT_ARTICLES;
  1404.   
  1405. ***************
  1406. *** 559,564 ****
  1407. --- 562,568 ----
  1408.   
  1409.       if (last_motd >= cur_motd) return 0;
  1410.   
  1411. +     unlink(dot_motd);
  1412.       fclose(open_file(dot_motd, OPEN_CREATE|MUST_EXIST));
  1413.   
  1414.       clrdisp();
  1415. *** ./LAST/nnusage.sh    Wed Apr 25 19:15:54 1990
  1416. --- nnusage.sh    Tue Sep  4 16:17:55 1990
  1417. ***************
  1418. *** 13,24 ****
  1419.           shift ;;
  1420.       -t)    SORTMODE="+1nr"
  1421.           shift ;;
  1422.       *)    LOOP=false
  1423.       esac
  1424.   done
  1425.   
  1426.   if [ -f $DB/acct -a -f $BIN/nnacct ] ; then
  1427. !     $BIN/nnacct -r $OPT $@ | sort $SORTMODE
  1428.       exit
  1429.   fi
  1430.   
  1431. --- 13,33 ----
  1432.           shift ;;
  1433.       -t)    SORTMODE="+1nr"
  1434.           shift ;;
  1435. +     -at)    OPT="$OPT -a"
  1436. +         ALL=true
  1437. +         SORTMODE="+1nr"
  1438. +         shift ;;
  1439. +     -*)    echo "$0: unknown option: $1"
  1440. +         exit 1
  1441. +         ;;
  1442.       *)    LOOP=false
  1443. +         ;;
  1444.       esac
  1445.   done
  1446.   
  1447.   if [ -f $DB/acct -a -f $BIN/nnacct ] ; then
  1448. !     echo "USER        USAGE  QUOTA  LAST_ACTIVE   COST/PERIOD"
  1449. !     $BIN/nnacct -r $OPT $@ | sed -e 1d | sort $SORTMODE
  1450.       exit
  1451.   fi
  1452.   
  1453. *** ./LAST/pack_name.c    Tue May 22 12:53:56 1990
  1454. --- pack_name.c    Tue Sep  4 18:39:44 1990
  1455. ***************
  1456. *** 179,184 ****
  1457. --- 179,185 ----
  1458.       int lname, lfirst, lmiddle, llast, sep, i;
  1459.       int drop_space, prev_space;
  1460.       char *separator[SEP_MAXIMUM];
  1461. +     int ignore_braces = 0;
  1462.   
  1463.       dest[0] = NUL;
  1464.   
  1465. ***************
  1466. *** 185,190 ****
  1467. --- 186,192 ----
  1468.       if (source == NULL || source[0] == NUL)
  1469.       return 0;
  1470.   
  1471. + full_scan:
  1472.       p = source, q = namebuf, n = 0;
  1473.       maxq = namebuf + sizeof namebuf - 1;
  1474.   
  1475. ***************
  1476. *** 197,220 ****
  1477.           if (q == namebuf) continue;
  1478.           break;
  1479.       }
  1480.       if (IGNORE(c)) continue;
  1481.       if (q == namebuf && IS_SPACE(c)) continue;
  1482.       if (c == '(') {
  1483. !         if (*p == ')') {
  1484. !         p++;
  1485. !         continue;
  1486. !         }
  1487. !         if (n++ == 0) {
  1488.           q = namebuf;
  1489.           goto new_partition;
  1490.           }
  1491.           continue;
  1492.       }
  1493. !     if (c == ')') {
  1494. !         if (--n == 0) break;
  1495. !         continue;
  1496. !     }
  1497. !     if (n > 1) continue;
  1498.       if (q >= maxq) break;
  1499.       *q++ = c;
  1500.       if (IS_SEPARATOR(c)) {
  1501. --- 199,219 ----
  1502.           if (q == namebuf) continue;
  1503.           break;
  1504.       }
  1505. +     if (c == ')') {
  1506. +         if (--n == 0 && !ignore_braces) break;
  1507. +         continue;
  1508. +     }
  1509.       if (IGNORE(c)) continue;
  1510.       if (q == namebuf && IS_SPACE(c)) continue;
  1511.       if (c == '(') {
  1512. !         if (n++ == 0 && !ignore_braces) {
  1513.           q = namebuf;
  1514.           goto new_partition;
  1515.           }
  1516.           continue;
  1517.       }
  1518. !     if (n > 0)
  1519. !         if (ignore_braces || n > 1) continue;
  1520.       if (q >= maxq) break;
  1521.       *q++ = c;
  1522.       if (IS_SEPARATOR(c)) {
  1523. ***************
  1524. *** 239,244 ****
  1525. --- 238,248 ----
  1526.       }
  1527.   
  1528.       *q = NUL;
  1529. +     if (namebuf[0] == NUL && !ignore_braces ) {
  1530. +     ignore_braces = 1;
  1531. +     goto full_scan;
  1532. +     }
  1533.   
  1534.       if (namebuf[0] == NUL) return 0;
  1535.   
  1536. *** ./LAST/patchlevel.h    Thu Jul 19 18:12:22 1990
  1537. --- patchlevel.h    Tue Sep 18 12:24:06 1990
  1538. ***************
  1539. *** 20,26 ****
  1540.    *    1990-07-09: Patch #7 (6.4.7) - LOW
  1541.    *    1990-07-16: Patch #8 (6.4.8) - HIGH
  1542.    *    1990-07-19: Patch #9 (6.4.9) - MEDIUM
  1543.    */
  1544.   
  1545. ! #define PATCHLEVEL 9
  1546.   
  1547. --- 20,27 ----
  1548.    *    1990-07-09: Patch #7 (6.4.7) - LOW
  1549.    *    1990-07-16: Patch #8 (6.4.8) - HIGH
  1550.    *    1990-07-19: Patch #9 (6.4.9) - MEDIUM
  1551. +  *    1990-09-18: Patch #10 (6.4.10) - HIGH
  1552.    */
  1553.   
  1554. ! #define PATCHLEVEL 10
  1555.   
  1556. *** ./LAST/prefix.c    Mon Jul 16 17:38:53 1990
  1557. --- prefix.c    Wed Aug 22 17:12:23 1990
  1558. ***************
  1559. *** 28,34 ****
  1560.   #ifdef AVOID_SHELL_EXEC
  1561.       fprintf(f, ":\n");
  1562.   #else
  1563. !     fprintf(f, "#!/bin/sh\n");
  1564.   #endif
  1565.       fprintf(f, "\n# Generated by nn release %s at %s\n\n",
  1566.              version_id, date_time((time_t)0));
  1567. --- 28,34 ----
  1568.   #ifdef AVOID_SHELL_EXEC
  1569.       fprintf(f, ":\n");
  1570.   #else
  1571. !     fprintf(f, "#!%s\n", SHELL);
  1572.   #endif
  1573.       fprintf(f, "\n# Generated by nn release %s at %s\n\n",
  1574.              version_id, date_time((time_t)0));
  1575. *** ./LAST/save.c    Mon Jul 16 17:38:53 1990
  1576. --- save.c    Tue Sep 11 17:53:17 1990
  1577. ***************
  1578. *** 23,28 ****
  1579. --- 23,30 ----
  1580.   export int  conf_append = 0;
  1581.   export int  conf_create = 1;
  1582.   
  1583. + export char *saved_header_escape = "~";
  1584.   export char *print_header_lines = "FDGS";
  1585.   export char *save_header_lines = "FDNS";
  1586.   static char *short_header_lines;
  1587. ***************
  1588. *** 523,530 ****
  1589.       while (ftell(art) < ah->lpos && fgets(copybuf, 512, art)) {
  1590.       lcount++;
  1591.       if (rot13_active) rot13_line(copybuf);
  1592. !     if (with_header && is_header_line(copybuf))
  1593. !         fputc('~', save_file);
  1594.       fputs(copybuf, save_file);
  1595.       if (s_pipe) goto broken_pipe;
  1596.       }
  1597. --- 525,532 ----
  1598.       while (ftell(art) < ah->lpos && fgets(copybuf, 512, art)) {
  1599.       lcount++;
  1600.       if (rot13_active) rot13_line(copybuf);
  1601. !     if (saved_header_escape && with_header && is_header_line(copybuf))
  1602. !         fputs(saved_header_escape, save_file);
  1603.       fputs(copybuf, save_file);
  1604.       if (s_pipe) goto broken_pipe;
  1605.       }
  1606. *** ./LAST/sequence.c    Thu Jul 19 18:12:22 1990
  1607. --- sequence.c    Fri Aug 31 14:11:00 1990
  1608. ***************
  1609. *** 445,451 ****
  1610.       if (hex_group_args) {
  1611.           sscanf(group, "%x", &gnum);
  1612.           if (gnum < 0 || gnum >= master.number_of_groups) continue;
  1613. !         gh = &active_groups[gnum];
  1614.           if (enter_sequence(SHOW_NORMAL, gh)) any++;
  1615.           continue;
  1616.       }
  1617. --- 445,451 ----
  1618.       if (hex_group_args) {
  1619.           sscanf(group, "%x", &gnum);
  1620.           if (gnum < 0 || gnum >= master.number_of_groups) continue;
  1621. !         gh = ACTIVE_GROUP(gnum);
  1622.           if (enter_sequence(SHOW_NORMAL, gh)) any++;
  1623.           continue;
  1624.       }
  1625. *** ./LAST/sort.c    Mon Apr 23 18:37:14 1990
  1626. --- sort.c    Tue Sep  4 16:48:57 1990
  1627. ***************
  1628. *** 98,104 ****
  1629.   
  1630.       if ((**ah1).t_stamp > (**ah2).t_stamp) return 1;
  1631.       if ((**ah1).t_stamp < (**ah2).t_stamp) return -1;
  1632. !     return 0;
  1633.   }
  1634.   
  1635.   /* data_subj_date can only be used after root_t_stamp is set */
  1636. --- 98,104 ----
  1637.   
  1638.       if ((**ah1).t_stamp > (**ah2).t_stamp) return 1;
  1639.       if ((**ah1).t_stamp < (**ah2).t_stamp) return -1;
  1640. !     return order_arrival(ah1, ah2);
  1641.   }
  1642.   
  1643.   /* data_subj_date can only be used after root_t_stamp is set */
  1644. ***************
  1645. *** 131,137 ****
  1646.   {
  1647.       if ((**ah1).t_stamp > (**ah2).t_stamp) return 1;
  1648.       if ((**ah1).t_stamp < (**ah2).t_stamp) return -1;
  1649. !     return 0;
  1650.   }
  1651.   
  1652.   static order_from_date(ah1, ah2)
  1653. --- 131,137 ----
  1654.   {
  1655.       if ((**ah1).t_stamp > (**ah2).t_stamp) return 1;
  1656.       if ((**ah1).t_stamp < (**ah2).t_stamp) return -1;
  1657. !     return order_arrival(ah1, ah2);
  1658.   }
  1659.   
  1660.   static order_from_date(ah1, ah2)
  1661. *** ./LAST/term.c    Thu Jul 19 18:12:23 1990
  1662. --- term.c    Fri Sep  7 19:49:25 1990
  1663. ***************
  1664. *** 84,89 ****
  1665. --- 84,90 ----
  1666.   static char keypad_local[64], keypad_xmit[64];
  1667.   
  1668.   int  magic_cookie_glitch;    /* magic cookie size */
  1669. + int  ceol_standout_glitch;    /* hp brain damage! */
  1670.   
  1671.   #define putp(str)    tputs(str, 0, outc)
  1672.   
  1673. ***************
  1674. *** 308,313 ****
  1675. --- 309,323 ----
  1676.       terminal_speed = 30;
  1677.   }
  1678.   
  1679. + static raw_not_ok_error()
  1680. + {
  1681. +     if (batch_mode) return 0;
  1682. +     user_error("Not prepared for terminal i/o");
  1683. + }
  1684. + #define    RAW_CHECK    if (terminal_speed == 0) return raw_not_ok_error()
  1685. + #define BATCH_CHECK    if (terminal_speed == 0) return 0
  1686.   init_term(full)
  1687.   int full;
  1688.   {
  1689. ***************
  1690. *** 319,324 ****
  1691. --- 329,336 ----
  1692.       term_name = "batch";
  1693.       close(0);
  1694.       open("/dev/null", 0);
  1695. +     STANDOUT = 0;
  1696. +     cookie_size = 1;
  1697.       return;
  1698.       }
  1699.   
  1700. ***************
  1701. *** 380,385 ****
  1702. --- 392,398 ----
  1703.       cookie_size = tgetnum("sg");
  1704.   
  1705.       WRAP = tgetflag("am");
  1706. +     ceol_standout_glitch = tgetflag("xs");
  1707.   
  1708.       opt_cap("ti", enter_ca_mode);
  1709.       opt_cap("te", exit_ca_mode);
  1710. ***************
  1711. *** 478,483 ****
  1712. --- 491,498 ----
  1713.   
  1714.   home()
  1715.   {
  1716. +     BATCH_CHECK;
  1717.       putp(cursor_home);
  1718.   }
  1719.   
  1720. ***************
  1721. *** 497,502 ****
  1722. --- 512,519 ----
  1723.   gotoxy(c, l)
  1724.   int c, l;
  1725.   {
  1726. +     BATCH_CHECK;
  1727.       curxy_c = c; curxy_l = l;
  1728.       putp(tgoto(cursor_address, c, l));
  1729.   }
  1730. ***************
  1731. *** 503,508 ****
  1732. --- 520,527 ----
  1733.   
  1734.   clrdisp()
  1735.   {
  1736. +     BATCH_CHECK;
  1737.   #ifdef USE_TERMINFO
  1738.       putp(clear_screen);        /* tputs is broken on UNISYS I've been told */
  1739.   #else
  1740. ***************
  1741. *** 514,519 ****
  1742. --- 533,540 ----
  1743.   
  1744.   clrline()
  1745.   {
  1746. +     BATCH_CHECK;
  1747.       putp(clr_eol);
  1748.       fl;
  1749.   }
  1750. ***************
  1751. *** 523,528 ****
  1752. --- 544,551 ----
  1753.   {
  1754.       register int olineno= lineno;
  1755.   
  1756. +     BATCH_CHECK;
  1757.       if (HAS_CAP(clr_eos)) {
  1758.   #ifdef USE_TERMINFO
  1759.       putp(clr_eos);
  1760. ***************
  1761. *** 581,586 ****
  1762. --- 604,610 ----
  1763.       fmt = va_arg1(char *);
  1764.   
  1765.       if (!so_active) {
  1766. +     if (ceol_standout_glitch) highlight(0);
  1767.       vprintf(fmt, va_args2toN);
  1768.       return;
  1769.       }
  1770. ***************
  1771. *** 619,625 ****
  1772.   
  1773.       if ((so_b & 1) && (!STANDOUT || !cookie_size)) putchar(SP);
  1774.   
  1775. !     if (STANDOUT) putp(enter_standout_mode);
  1776.   
  1777.       fputs(so_buf, stdout);
  1778.   
  1779. --- 643,652 ----
  1780.   
  1781.       if ((so_b & 1) && (!STANDOUT || !cookie_size)) putchar(SP);
  1782.   
  1783. !     if (STANDOUT) {
  1784. !     if (ceol_standout_glitch) clrline();
  1785. !     putp(enter_standout_mode);
  1786. !     }
  1787.   
  1788.       fputs(so_buf, stdout);
  1789.   
  1790. ***************
  1791. *** 679,684 ****
  1792. --- 706,713 ----
  1793.   
  1794.   visual_on()
  1795.   {
  1796. +     BATCH_CHECK;
  1797.       if (HAS_CAP(enter_ca_mode)) {
  1798.       putp(enter_ca_mode);
  1799.       is_visual = 1;
  1800. ***************
  1801. *** 711,716 ****
  1802. --- 740,747 ----
  1803.   #ifdef CBREAK
  1804.   raw()
  1805.   {
  1806. +     RAW_CHECK;
  1807.       if (is_raw == 1)
  1808.       return;
  1809.       is_raw = 1;
  1810. ***************
  1811. *** 726,731 ****
  1812. --- 757,763 ----
  1813.   {
  1814.       if (is_raw == 0)
  1815.       return 0;
  1816. +     RAW_CHECK;
  1817.       RAW_MODE_OFF;
  1818.       is_raw = 0;
  1819.       return 1;
  1820. ***************
  1821. *** 736,741 ****
  1822. --- 768,775 ----
  1823.   
  1824.   raw()
  1825.   {
  1826. +     RAW_CHECK;
  1827.       if (!flow_control) {
  1828.       if (!must_set_raw) return;
  1829.       must_set_raw = 0;
  1830. ***************
  1831. *** 754,759 ****
  1832. --- 788,795 ----
  1833.   
  1834.       if (!is_raw) return 0;
  1835.   
  1836. +     RAW_CHECK;
  1837.       RAW_MODE_OFF;
  1838.   
  1839.       is_raw = 0;
  1840. ***************
  1841. *** 766,771 ****
  1842. --- 802,808 ----
  1843.       int was_raw = is_raw;
  1844.   
  1845.       if (is_raw) {
  1846. +     RAW_CHECK;
  1847.       RAW_MODE_OFF;
  1848.       is_raw = 0;
  1849.       }
  1850. ***************
  1851. *** 781,786 ****
  1852. --- 818,825 ----
  1853.   
  1854.   flush_input()
  1855.   {
  1856. +     BATCH_CHECK;
  1857.   #ifdef HAVE_TERMIO
  1858.       ioctl(0, TCFLSH, 0);
  1859.       do_flush_input = 1;
  1860. ***************
  1861. *** 1316,1321 ****
  1862. --- 1355,1362 ----
  1863.   
  1864.   ding()
  1865.   {
  1866. +     BATCH_CHECK;
  1867.       putp(bell_str);
  1868.       fl;
  1869.   }
  1870. ***************
  1871. *** 1512,1517 ****
  1872. --- 1553,1560 ----
  1873.       msg_ptr = msg_stack;
  1874.       }
  1875.   
  1876. +     BATCH_CHECK;
  1877.       gotoxy(0, Lines-1);
  1878.       fputs(errmsg, stdout);
  1879.       clrline();
  1880. ***************
  1881. *** 1524,1529 ****
  1882. --- 1567,1574 ----
  1883.   clrmsg(col)
  1884.   int col;
  1885.   {
  1886. +     BATCH_CHECK;
  1887.       gotoxy(0, prompt_line + 1);
  1888.       clrpage(prompt_line + 1);
  1889.       if (col >= 0)
  1890. ***************
  1891. *** 1544,1549 ****
  1892. --- 1589,1596 ----
  1893.       static char saved_p[FILENAME];
  1894.       use_vararg;
  1895.   
  1896. +     BATCH_CHECK;
  1897.       start_vararg;
  1898.   
  1899.       fmt = va_arg1(char *);
  1900. ***************
  1901. *** 1639,1644 ****
  1902. --- 1686,1693 ----
  1903.   {
  1904.       int was_raw, c, dmp;
  1905.   
  1906. +     BATCH_CHECK;
  1907.       was_raw = is_raw;
  1908.       if (!is_raw) raw();
  1909.       if (line == 0)
  1910. ***************
  1911. *** 1702,1707 ****
  1912. --- 1751,1761 ----
  1913.   {
  1914.       int c;
  1915.   
  1916. +     if (batch_mode) {
  1917. +     putchar(NL);
  1918. +     return 0;
  1919. +     }
  1920.       pg_line++;
  1921.       if (pg_line < Lines) {
  1922.       gotoxy(pg_col, pg_line);
  1923. ***************
  1924. *** 1740,1757 ****
  1925.   pg_indent(pos)
  1926.   int pos;
  1927.   {
  1928.       gotoxy(pg_col + pos, pg_line);
  1929.   }
  1930.   
  1931.   pg_end()
  1932.   {
  1933.       if (pg_quit == 0 && pg_next() == 0)
  1934. !     any_key(0);
  1935.   
  1936.       if (pg_regexp) {
  1937.       freeobj(pg_regexp);
  1938.       pg_regexp = NULL;
  1939.       }
  1940.   }
  1941.   
  1942.   
  1943. --- 1794,1819 ----
  1944.   pg_indent(pos)
  1945.   int pos;
  1946.   {
  1947. +     BATCH_CHECK;
  1948.       gotoxy(pg_col + pos, pg_line);
  1949.   }
  1950.   
  1951.   pg_end()
  1952.   {
  1953. +     int c;
  1954.       if (pg_quit == 0 && pg_next() == 0)
  1955. !     c = any_key(0);
  1956. !     else
  1957. !     c = K_interrupt;
  1958.   
  1959.       if (pg_regexp) {
  1960.       freeobj(pg_regexp);
  1961.       pg_regexp = NULL;
  1962.       }
  1963. +     return c == K_interrupt ? -1 : 0;
  1964.   }
  1965.   
  1966.   
  1967. ***************
  1968. *** 1758,1763 ****
  1969. --- 1820,1827 ----
  1970.   user_delay(ticks)
  1971.   int ticks;
  1972.   {
  1973. +     BATCH_CHECK;
  1974.       if (ticks <= 0 || conf_dont_sleep) {
  1975.       printf(" <>");
  1976.       any_key(10000);
  1977. *** ./LAST/variable.c    Thu Jul 19 18:12:24 1990
  1978. --- variable.c    Mon Sep 17 15:30:45 1990
  1979. ***************
  1980. *** 16,21 ****
  1981. --- 16,23 ----
  1982.       *decode_header_file,
  1983.       *default_distribution,
  1984.       *default_save_file,
  1985. +     *distribution_follow,
  1986. +     *distribution_post,
  1987.       *editor_program,
  1988.       *extra_mail_headers,
  1989.       *extra_news_headers,
  1990. ***************
  1991. *** 39,44 ****
  1992. --- 41,47 ----
  1993.       *response_dflt_answer,
  1994.       *save_counter_format,
  1995.       *save_header_lines,
  1996. +     *saved_header_escape,
  1997.       *shade_on_attr,
  1998.       *shade_off_attr,
  1999.       *spell_checker,
  2000. ***************
  2001. *** 49,54 ****
  2002. --- 52,58 ----
  2003.   
  2004.   import int            /* boolean variables */
  2005.       also_cross_postings,
  2006. +     also_full_digest,
  2007.       also_subgroups,
  2008.       append_sig_mail,
  2009.       append_sig_post,
  2010. ***************
  2011. *** 218,223 ****
  2012. --- 222,228 ----
  2013.       int  var_flags;
  2014.       char **var_addr;
  2015.   } variables[] = {
  2016. +     "also-full-digest",        BOOL 0,        (char **)&also_full_digest,
  2017.       "also-subgroups",        BOOL INIT 0,    (char **)&also_subgroups,
  2018.       "append-signature-mail",     BOOL 0,        (char **)&append_sig_mail,
  2019.       "append-signature-post",     BOOL 0,        (char **)&append_sig_post,
  2020. ***************
  2021. *** 259,264 ****
  2022. --- 264,270 ----
  2023.       "edit-response-check",     BOOL 0,        (char **)&empty_answer_check,
  2024.       "edit-unshar-command",     BOOL 0,        (char **)&edit_unshar_command,
  2025.       "editor",            STR 0,        (char **)&editor_program,
  2026. +     "embedded-header-escape",    STR 0,        (char **)&saved_header_escape,
  2027.       "entry-report-limit",     INT 0,        (char **)&entry_message_limit,
  2028.       "erase-key",        KEY 0,        (char **)&erase_key,
  2029.       "expert",            BOOL 4,        (char **)&novice,
  2030. ***************
  2031. *** 267,272 ****
  2032. --- 273,279 ----
  2033.       "flush-typeahead",        BOOL 0,        (char **)&flush_typeahead,
  2034.       "folder",            STR 2,        (char **)&folder_directory,
  2035.       "folder-save-file",        STR 3,        (char **)&folder_save_file,
  2036. +     "follow-distribution",    STR 0,        (char **)&distribution_follow,
  2037.       "fsort",            BOOL 2,        (char **)&dont_sort_folders,
  2038.       "header-lines",        STR 0,        (char **)&header_lines,
  2039.       "help-key",            KEY 0,        (char **)&help_key,
  2040. ***************
  2041. *** 320,325 ****
  2042. --- 327,333 ----
  2043.       "overlap",            INT 0,        (char **)&overlap,
  2044.       "pager",            STR SAFE 3,    (char **)&pager,
  2045.       "patch-command",        STR SAFE 1,    (char **)patch_command,
  2046. +     "post-distribution",    STR 0,        (char **)&distribution_post,
  2047.       "preview-continuation",     INT 0,        (char **)&preview_continuation,
  2048.       "preview-mark-read",    BOOL 0,        (char **)&preview_mark_read,
  2049.       "previous-also-read",    BOOL 0,        (char **)&prev_also_read,
  2050. ***************
  2051. *** 534,540 ****
  2052.   
  2053.        case V_BOOLEAN:
  2054.   
  2055. !     if (val_string)
  2056.           if (val_string[0] == 'o')
  2057.           on = val_string[1] == 'n'; /* on */
  2058.           else
  2059. --- 542,549 ----
  2060.   
  2061.        case V_BOOLEAN:
  2062.   
  2063. !     adjust(val_string);
  2064. !     if (val_string && *val_string != NUL)
  2065.           if (val_string[0] == 'o')
  2066.           on = val_string[1] == 'n'; /* on */
  2067.           else
  2068. ***************
  2069. *** 1056,1060 ****
  2070. --- 1065,1114 ----
  2071.       if (!all && (var->var_flags & V_MODIFIED) == 0) continue;
  2072.       str = var_value(var, tag);
  2073.       fprintf(f, "%s%s='%s'\n", all ? tag : "", var->var_name, str);
  2074. +     }
  2075. + }
  2076. + /*
  2077. +  *    var_options(string_var *, options, result *)
  2078. +  *
  2079. +  *    test whether "string_var" contains any of the options
  2080. +  *    listed in "options" (NUL-separated list of names ended with 
  2081. +  *    double NUL).  On return, string_var is advanced over all
  2082. +  *    recognized options and the result will have the bits corresponding
  2083. +  *    to the recognized options set.
  2084. +  */
  2085. + var_options(str, options, res)
  2086. + char **str;
  2087. + register char *options;
  2088. + flag_type *res;
  2089. + {
  2090. +     char word[128];
  2091. +     char *optab[32];
  2092. +     register char **op, *wp, c;
  2093. +     register int n;
  2094. +     
  2095. +     for (op = optab; *options != NUL; op++, options++) {
  2096. +     *op = options;
  2097. +     while (*options) options++;
  2098. +     }
  2099. +     *op = NULL;
  2100. +     
  2101. +     *res = 0;
  2102. +     options = *str;
  2103. +     while (*options) {
  2104. +     for (wp = word; (c = *options) != NUL; *wp++ = c, options++)
  2105. +         if (isascii(c) && isspace(c)) break;
  2106. +     while ((c = *options) && isascii(c) && isspace(c)) options++;
  2107. +     *wp = NUL;
  2108. +     for (op = optab, n = 0; *op != NULL; op++, n++) {
  2109. +         if (strcmp(word, *op)) continue;
  2110. +         *res |= FLAG(n);
  2111. +         *str = options;
  2112. +         break;
  2113. +     }
  2114. +     if (*op == NULL) break;
  2115.       }
  2116.   }
  2117.